using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using Apache.Cassandra;


namespace Cassandraemon
{

	class ListCassandraEntityConverter<TInput, TOutput, TOutputItem> : CassandraEntityConverterBase<TInput, TOutput> where TOutput : IEnumerable<TOutputItem>
	{
		
		public ListCassandraEntityConverter (CassandraEntity<TInput> entity) : base(entity) { }
		
		
		public TOutput ToFlatValueList()
		{
			if(!MappingUtil.IsValueTypeOrString(typeof(TOutputItem)))
			{
				throw new InvalidOperationException("You should specify valuetype list when use ToFlatValueList.");
			}
			
			if(typeof(TInput).Equals(typeof(CounterColumn)) ||
			   typeof(TInput).Equals(typeof(CounterSuperColumn)) ||
			   typeof(TInput).Equals(typeof(List<CounterColumn>)) ||
			   typeof(TInput).Equals(typeof(List<CounterSuperColumn>)))
			{
				if(!typeof(TOutputItem).Equals(typeof(long)))
				{
					throw new InvalidOperationException("You should specify long type when you get CounterColumn and use ToFlatValueList.");
				}
			}

			if(Entity.Data == null) return Object;
			
			var list = GetFlatValueList<TOutputItem>(Entity.Data);
			
			if(list == null) return Object;
			if(list.Count == 0) return Object;
			
			return (TOutput)(object)list;
		}
		
		public TOutput ToFlatNameList()
		{
			if(!MappingUtil.IsValueTypeOrString(typeof(TOutputItem)))
			{
				throw new InvalidOperationException("You should specify valuetype list when use ToFlatNameList.");
			}

			if(Entity.Data == null) return Object;
			
			var list = GetFlatNameList<TOutputItem>(Entity.Data);
			
			if(list == null) return Object;
			if(list.Count == 0) return Object;
			
			return (TOutput)(object)list;
		}
		
		public TOutput ToObjectList()
		{
			if(typeof(TInput).Equals(typeof(CounterColumn)) ||
			   typeof(TInput).Equals(typeof(CounterSuperColumn)) ||
			   typeof(TInput).Equals(typeof(List<CounterColumn>)) ||
			   typeof(TInput).Equals(typeof(List<CounterSuperColumn>)))
			{
				throw new InvalidOperationException("You can't use ToObjectList when you get CounterColumn.");
			}

			if(Entity.Data == null) return Object;
			
			var columns = GetNestedColumnList(Entity.Data);
			
			if(columns == null) return Object;
			if(columns.Count == 0) return Object;
			
			var list = columns.ConvertAll(x => MappingUtil.MappingObject<TOutputItem>(x));
			return (TOutput)(object)list;
		}
		
		
	}
}
